#include "MainManger.h"
#include "DBManger.h"
#include "FishControl.h"
#include "HttpManger.h"
#include "StatusLamp.h"
#include "AliIoTControl.h"
#include <ArduinoOTA.h>
#include <ESP8266mDNS.h>
#include <MacDefind.h>
#include <vector>
#include <TimeLib.h>

enum STMac st_mac = _ST_SHUTDOWM;
const int8_t timeZone = 8;
const int8_t minutesTimeZone = 0;
#define PUSHSVR_SEC_KEY "SCU66612Tc0928e9b819a0a7baa3e2b42fdf4ab095dd0aeea9097c"

MainManger::MainManger(/* args */)
    : _wifiFaile(0), _light(false), _ntp(ntpUDP, "ntp1.aliyun.com", 3600 * 8)
{
}

MainManger::~MainManger() {}

void MainManger::init()
{

    // NTP.onNTPSyncEvent(
    //     std::bind(&MainManger::ntpSyncEvent, this, std::placeholders::_1));

    // WiFi.mode(WIFI_STA);

    // JsonArray wlans = dbManger.getWiFiEntry();
    // for (JsonArray::iterator it = wlans.begin(); it != wlans.end(); ++it)
    // {
    //     String ssid = (*it)["ssid"] | "GDCN_1102";
    //     String passphrase = (*it)["passphrase"] | "kktt0219";
    //     // Serial.printf("%s %s \r\n", ssid.c_str(), passphrase.c_str());
    //     _wifiMulti.addAP(ssid.c_str(), passphrase.c_str());
    // }

    WiFi.setSleepMode(WIFI_LIGHT_SLEEP);
    st_mac = _ST_BOOTING;
    request.setDebug(false);
    request.onReadyStateChange(std::bind(&MainManger::requestCB, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    loadTimeCfg();
}

// void MainManger::ntpSyncEvent(NTPSyncEvent_t ntpEvent)
// {
//     if (ntpEvent)
//     {
//         Serial.print("Time Sync error: ");
//         if (ntpEvent == noResponse)
//         {
//             Serial.println(F("NTP server not reachable"));
//             _wifiFaile++;
//         }
//         else if (ntpEvent == invalidAddress)
//             Serial.println(F("Invalid NTP server address"));
//         else if (ntpEvent == requestSent)
//             Serial.println(F("NTP request sent, waiting for response"));
//         else if (ntpEvent == errorSending)
//             Serial.println(F("An error happened while sending the request"));

//         if (_wifiFaile > 5)
//         {
//             _wifiFaile = 0;
//             pushMessage("同步时间失败次数已达5次");
//             // ESP.restart();
//         }
//         stLamp.setSt(StatusLamp::_ST_ERROR);
//     }
//     else
//     {
//         _wifiFaile = 0;
//         stLamp.setSt(StatusLamp::_ST_RUNNING);
//         Serial.printf("Got NTP time: %s\n",
//                       NTP.getTimeDateString(NTP.getLastNTPSync()).c_str());
//     }
// }

void MainManger::requestCB(void *optParm, asyncHTTPrequest *request, int readyState)
{
    if (readyState == 4)
    {
        Serial.println(request->responseText());
        Serial.println();
    }
}

time_t MainManger::getEpochTime()
{
    return _ntp.getEpochTime();
}

bool MainManger::connect()
{
    // if (WL_CONNECTED == _wifiMulti.run())
    // {
    //     Serial.println(F("connected"));
    //     return true;
    // }
    // else if (millis() - _last_led >= 200)
    // {
    //     _last_led = millis();
    //     Serial.print(F("."));
    //     return false;
    // }
    // else
    // {
    //     return false;
    // }
    return true;
}

void MainManger::loop()
{
    switch (st_mac)
    {
    case _ST_BOOTING:
    {
        Serial.println(F("BOOTTING"));
        st_mac = _ST_INITING;
    }
    break;
    case _ST_INITING:
    {
        if (connect())
        {
            st_mac = _ST_UPDATE_INIT;
        }
    }
    break;
    case _ST_UPDATE_INIT:
    {
        Serial.printf("SSID: %s\r\n", WiFi.SSID().c_str());
        Serial.printf("IP address: %s\r\n", WiFi.localIP().toString().c_str());

        if (MDNS.begin(_MDNS_NAME_))
        {
            Serial.println("mDNS responder started");
            httpManger.begin();
            MDNS.addService("http", "tcp", 80);
            ArduinoOTA.begin();
            _ntp.begin();
            st_mac = _ST_REDAY;
            stLamp.setSt(StatusLamp::_ST_SYNC_NTP);
        }
    }
    break;
    case _ST_REDAY:
    {

        // NTP.begin("ntp3.aliyun.com", timeZone, false, minutesTimeZone);
        // NTP.setInterval(3600);
        // NTP.getLastNTPSync();
        if (_ntp.forceUpdate())
        {
            aliIotControl.begin();
            st_mac = _ST_RUNNING;
            stLamp.setSt(StatusLamp::_ST_RUNNING);
            _wifiFaile = 0;
            pushMessage("设备上线了.");
        }
        else
        {
            ArduinoOTA.handle();
            MDNS.update();
            httpManger.handle();
            // aliIotControl.loop();
            // Run();
            if (_wifiFaile ++ > 300) {
                pushMessage("同步时间失败次数已达300次");
                _wifiFaile = 0;
            }
        }
    }
    break;
    case _ST_RUNNING:
    {
        _ntp.update();
        ArduinoOTA.handle();
        MDNS.update();
        httpManger.handle();
        aliIotControl.loop();
        Run();
    }
    break;
    default:
        break;
    }
}

bool MainManger::Run()
{
    HT_BEGIN();

    for (;;)
    {
        // _ex_timer.start(30000);
        // PT_WAIT_UNTIL(_ex_timer.expired());

        HT_WAIT_UNTIL(checkLight());
        // Serial.printf_P(PSTR("%s : CHAMGE Lamp %d \r\n"), NTP.getTimeDateString().c_str(), _light);
        Serial.printf_P(PSTR("%s : CHAMGE Lamp %d \r\n"), _ntp.getFormattedTime().c_str(), _light);
        fishCtrl.switchOnLamp(_light);
        // aliIotControl.updateStatus();
    }

    HT_END();
}

void MainManger::loadTimeCfg()
{
    JsonArray timeOn = dbManger.getLightEntry();
    _timeOns.clear();
    for (JsonArray::iterator it = timeOn.begin(); it != timeOn.end(); ++it)
    {
        TimeOnEntry entry;
        entry.start = (*it)["s"];
        entry.end = (*it)["e"];
        _timeOns.push_back(entry);
    }
}

bool MainManger::checkLight()
{
#if DEBUG
    int hours = second();
#else
    int hours = hour();
#endif
    // if (!_ntp.update())
    // {
    //     _light = false;
    //     return false;
    // }

    int wday = weekday();
    bool onoff = false;
    bool ret = false;
    if (wday == 1)
    {
        //星期天全天开灯
        if (hours >= 8 && hours < 23)
        {
            onoff = true;
        }
    }
    else
    {
        for (size_t i = 0; i < _timeOns.size(); i++)
        {

            if (hours >= _timeOns[i].start && hours < _timeOns[i].end)
            {
                onoff = true;
                break;
            }
        }
    }

    if (onoff != _light)
    {
        _light = onoff;
        ret = true;
#if DEBUG
        Serial.printf("%d:%d:%d [%d]\r\n", hour(), minute(), second(), _light);
#endif
    }

    return ret;
}

void MainManger::pushMessage(String msg)
{
#ifndef DEBUG
    if (request.readyState() == 0 || request.readyState() == 4)
    {
        String url = "http://sc.ftqq.com/";
        url += PUSHSVR_SEC_KEY;
        url += ".send?text=";
        url += msg;
        url += "-";
        url += _ntp.getFormattedTime();
        url += "&desp=";
        url += _ntp.getEpochTime(); // NTP.getLastNTPSync();
        request.open("GET", url.c_str());
        request.send();
    }
#endif
}
